' Copyright (c) Microsoft Corporation.  All rights reserved.
Imports System
Imports System.Collections.Generic
Imports System.Data.Metadata.Edm
Imports System.Diagnostics
Imports System.Linq

Namespace EdmMetadataHelpersVB
    ''' <summary>
    ''' This class shreds the metadata in an EdmItemCollection into a 
    ''' more friendly format (i.e. the informaiton in a CSDL file)
    ''' </summary>
    ''' <remarks></remarks>
    Public Class EdmCsdlCatalog
        ' Methods
        Public Sub New(ByVal items As EdmItemCollection)
            Me._associations = New List(Of AssociationType)
            Me._properties = New List(Of EdmProperty)
            Me._navigationProperties = New List(Of NavigationProperty)
            Me._primitives = New List(Of PrimitiveType)
            Me._entities = New List(Of EntityType)
            Me._functions = New List(Of EdmFunction)
            Me._containers = New List(Of EntityContainer)
            Me._sets = New List(Of EntitySetBase)
            Me.Register(items)
        End Sub

        Public Sub New(ByVal csdlFilepath As String)
            Me.New(New EdmItemCollection(New String() {csdlFilepath}))
        End Sub
        ''' <summary>
        ''' Shreds the EdmItemCollection
        ''' </summary>
        Public Sub Register(ByVal items As EdmItemCollection)
            Dim item As GlobalItem
            For Each item In items
                Me.Register(item)
            Next
        End Sub

        Private Sub Register(ByVal member As EdmMember)
            Dim kind As BuiltInTypeKind = member.BuiltInTypeKind
            If (kind <> BuiltInTypeKind.NavigationProperty) Then
                If (kind <> BuiltInTypeKind.EdmProperty) Then
                    Debugger.Break()
                Else
                    Dim Prop As EdmProperty = TryCast(member, EdmProperty)
                    Me._properties.Add(Prop)
                End If
            Else
                Dim navigationProperty As NavigationProperty = TryCast(member, NavigationProperty)
                Me._navigationProperties.Add(navigationProperty)
            End If
        End Sub

        Private Sub Register(ByVal container As EntityContainer)
            Dim esb As EntitySetBase
            For Each esb In container.BaseEntitySets
                Me._sets.Add(esb)
            Next
            Me._containers.Add(container)
        End Sub

        Private Sub Register(ByVal type As EntityType)
            Dim member As EdmMember
            For Each member In type.Members
                Me.Register(member)
            Next
            Me._entities.Add(type)
        End Sub

        Private Sub Register(ByVal item As GlobalItem)
            Select Case item.BuiltInTypeKind
                Case BuiltInTypeKind.EntityContainer
                    Me.Register(TryCast(item, EntityContainer))
                    Return
                Case BuiltInTypeKind.EntityType
                    Me.Register(TryCast(item, EntityType))
                    Return
                Case BuiltInTypeKind.AssociationType
                    Me._associations.Add(TryCast(item, AssociationType))
                    Return
                Case BuiltInTypeKind.EdmFunction
                    Me._functions.Add(TryCast(item, EdmFunction))
                    Return
                Case BuiltInTypeKind.PrimitiveType
                    Me.Register(TryCast(item, PrimitiveType))
                    Return
            End Select
            Throw New Exception("Couldn't register {0}".Merge(New String() {item.BuiltInTypeKind.ToString}))
        End Sub

        Private Sub Register(ByVal type As PrimitiveType)
            Me._primitives.Add(type)
        End Sub


        ' Properties
        Public ReadOnly Property Associations() As IEnumerable(Of AssociationType)
            Get
                Return Me._associations
            End Get
        End Property

        Public ReadOnly Property AssociationSets() As IEnumerable(Of AssociationSet)
            Get
                Return Me.Sets.OfType(Of AssociationSet)()
            End Get
        End Property

        Public ReadOnly Property Containers() As IEnumerable(Of EntityContainer)
            Get
                Return Me._containers
            End Get
        End Property

        Public ReadOnly Property Entities() As IEnumerable(Of EntityType)
            Get
                Return Me._entities
            End Get
        End Property

        Public ReadOnly Property EntitySets() As IEnumerable(Of EntitySet)
            Get
                Return Me.Sets.OfType(Of EntitySet)()
            End Get
        End Property

        Public ReadOnly Property Functions() As IEnumerable(Of EdmFunction)
            Get
                Return Me._functions
            End Get
        End Property

        Public ReadOnly Property NavigationProperties() As IEnumerable(Of NavigationProperty)
            Get
                Return Me._navigationProperties
            End Get
        End Property

        Public ReadOnly Property Primitives() As IEnumerable(Of PrimitiveType)
            Get
                Return Me._primitives
            End Get
        End Property

        Public ReadOnly Property Properties() As IEnumerable(Of EdmProperty)
            Get
                Return Me._properties
            End Get
        End Property

        Public ReadOnly Property RelationshipsSets() As IEnumerable(Of RelationshipSet)
            Get
                Return Me.Sets.OfType(Of RelationshipSet)()
            End Get
        End Property

        Public ReadOnly Property Sets() As IEnumerable(Of EntitySetBase)
            Get
                Return Me._sets
            End Get
        End Property


        ' Fields
        Private _associations As List(Of AssociationType)
        Private _containers As List(Of EntityContainer)
        Private _entities As List(Of EntityType)
        Private _functions As List(Of EdmFunction)
        Private _navigationProperties As List(Of NavigationProperty)
        Private _primitives As List(Of PrimitiveType)
        Private _properties As List(Of EdmProperty)
        Private _sets As List(Of EntitySetBase)
    End Class
End Namespace

